package com.zenchn.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zenchn.annotation.OperLog;
import com.zenchn.entity.HttpDataResult;
import com.zenchn.entity.HttpResult;
import com.zenchn.entity.TSysScheduleTaskVO;
import com.zenchn.enums.DictTypeEnum;
import com.zenchn.enums.OperLogActionEnum;
import com.zenchn.exception.CheckException;
import com.zenchn.model.TSysDict;
import com.zenchn.model.TSysScheduleTask;
import com.zenchn.model.TSysScheduleTaskExample;
import com.zenchn.schedule.SchedulerService;
import com.zenchn.service.DictService;
import com.zenchn.service.ScheduleTaskService;
import io.swagger.annotations.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 调度任务模块控制器
 *
 * @author dingxinfa
 * @date 2020-04-20
 **/

@RestController
@RequestMapping(value = "scheduleTask")
@Api(value = "调度任务模块相关接口",tags="系统管理-定时任务")
@RequiresPermissions("schedule:task")
public class ScheduleTaskController {
    private final String MODULE="系统管理>定时任务";

    @Resource
    private ScheduleTaskService scheduleTaskService;

    @Resource
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Resource
    private SchedulerService schedulerService;

    @Resource
    private DictService dictService;
    /**
     * 分页获取调度任务列表
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperLog(module=MODULE,action= OperLogActionEnum.QUERY,detail="分页获取调度任务列表")
    @ApiOperation(value = "分页获取调度任务列表", notes = "分页获取调度任务列表")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "keyword", value = "调度任务名称，调度执行类"),
            @ApiImplicitParam(dataType = "Boolean", name = "isEnable", value = "是否启用"),
            @ApiImplicitParam(dataType = "Integer", name = "page", value = "当前第page页"),
            @ApiImplicitParam(dataType = "Integer", name = "pageSize", value = "每页pageSize数量")
    })
    @GetMapping(value = "/list")
    @RequiresPermissions("schedule:task")
    public ResponseEntity<HttpDataResult<PageInfo>> list(
            @RequestParam(required = false, value = "keyword") String keyword,
            @RequestParam(required = false, value = "isEnable") Boolean isEnable,
            @RequestParam(required = false, value = "page", defaultValue = "1") Integer page,
            @RequestParam(required = false, value = "pageSize", defaultValue = "10") Integer pageSize,
            HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpDataResult<PageInfo> result = new HttpDataResult<>(request.getRequestURI());

        TSysScheduleTaskExample configExample=new TSysScheduleTaskExample();
        TSysScheduleTaskExample.Criteria criteria=configExample.createCriteria();

        if (null!=keyword && !"".equals(keyword.trim())){
            criteria.andScheduleNameLike("%"+keyword.trim()+"%");

            TSysScheduleTaskExample.Criteria criteria2=configExample.createCriteria();
            criteria2.andSchedulerClassLike("%"+keyword.trim()+"%");


            if (null!=isEnable){
                criteria.andIsEnableEqualTo(isEnable);
                criteria2.andIsEnableEqualTo(isEnable);
            }
            configExample.or(criteria2);
        }else{

            if (null!=isEnable){
                criteria.andIsEnableEqualTo(isEnable);
            }
        }
        configExample.setOrderByClause("create_time desc");

        PageHelper.startPage(page,pageSize);
        PageInfo pageInfo = new PageInfo(scheduleTaskService.selectByExample(configExample));

        List<TSysDict> scheduleTypeList=dictService.selectByDictTypeId(DictTypeEnum.SCHEDULE_TYPE_GROUP.getId());

        List<TSysScheduleTask> scheduleTaskList=pageInfo.getList();
        List<TSysScheduleTaskVO> scheduleTaskVOList=new ArrayList<>();
        for(TSysScheduleTask scheduleTask:scheduleTaskList){
            TSysScheduleTaskVO scheduleTaskVO=new TSysScheduleTaskVO();
            BeanUtils.copyProperties(scheduleTask,scheduleTaskVO);

            if (null!=schedulerService.getTaskSchedulerMap(scheduleTask.getScheduleId())){
                scheduleTaskVO.setRunStatus(true);
            }else{
                scheduleTaskVO.setRunStatus(false);
            }
            for (TSysDict scheduleType:scheduleTypeList) {
                if (scheduleType.getDictId().equals(scheduleTask.getScheduleTypeId())) {
                    scheduleTaskVO.setScheduleTypeName(scheduleType.getDictName());
                }
            }
            scheduleTaskVOList.add(scheduleTaskVO);
        }

        pageInfo.setList(scheduleTaskVOList);

        result.setData(pageInfo);

        result.setMessage("OK");
        result.setStatus(HttpStatus.OK.value());
        return new ResponseEntity<>(result, HttpStatus.OK);
    }



    /***
     * 获取调度任务详情
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperLog(module=MODULE,action= OperLogActionEnum.QUERY,detail="获取调度任务详情")
    @ApiOperation(value = "获取调度任务详情", notes = "获取调度任务详情")
    @ApiImplicitParam(dataType = "String", name = "scheduleId", value = "调度任务ID", required = true)
    @GetMapping(value = "/getScheduleTask")
    public ResponseEntity<HttpDataResult<TSysScheduleTaskVO>> getScheduleTask(
            @RequestParam(value = "scheduleId") String scheduleId,
            HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpDataResult<TSysScheduleTaskVO> result = new HttpDataResult<>(request.getRequestURI());

        TSysScheduleTask scheduleTask=scheduleTaskService.selectByPrimaryKey(scheduleId);

        TSysScheduleTaskVO sysScheduleTaskVO=new TSysScheduleTaskVO();
        BeanUtils.copyProperties(scheduleTask,sysScheduleTaskVO);

        if (null!=schedulerService.getTaskSchedulerMap(scheduleTask.getScheduleId())){
            sysScheduleTaskVO.setRunStatus(true);
        }else{
            sysScheduleTaskVO.setRunStatus(false);
        }

        TSysDict scheduleType=dictService.selectByPrimaryKey(scheduleTask.getScheduleTypeId());
        if (null!=scheduleType){
            sysScheduleTaskVO.setScheduleTypeName(scheduleType.getDictName());
        }

        result.setData(sysScheduleTaskVO);
        result.setMessage("OK");
        result.setStatus(HttpStatus.OK.value());
        return new ResponseEntity<>(result, HttpStatus.OK);
    }


    /**
     * 修改调度任务保存提交
     * @param scheduleTask
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperLog(module=MODULE,action= OperLogActionEnum.UPDATE,detail="修改调度任务保存提交",isSaveRequestData=true)
    @ApiOperation(value = "修改调度任务保存提交", notes = "修改调度任务保存提交")
    @ApiParam(type = "TSysScheduleTask", name = "scheduleTask", value = "定时调度任务", required = true)
    @RequiresPermissions("schedule:task:modify")
    @PutMapping(value = "/modifySubmit")
    public ResponseEntity<HttpDataResult<String>> modifySubmit(
            @RequestBody @Valid TSysScheduleTask scheduleTask, BindingResult results,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpDataResult<String> result = new HttpDataResult<>(request.getRequestURI());

        if (results.hasErrors()){
            throw new CheckException(Objects.requireNonNull(results.getFieldError()).getDefaultMessage());
        }

        scheduleTaskService.updateByPrimaryKeySelective(scheduleTask);

        //启用|停用 调度任务
        if (scheduleTask.getIsEnable()){
            schedulerService.enableSchedule(scheduleTask);
        }else{
            if (null!=schedulerService.getTaskSchedulerMap(scheduleTask.getScheduleId())) {
                schedulerService.disableSchedule(scheduleTask);
            }
        }

        result.setData(scheduleTask.getScheduleId());
        result.setMessage("修改调度任务成功。");
        result.setStatus(HttpStatus.OK.value());
        return new ResponseEntity<>(result, HttpStatus.OK);
    }


    /***
     * 启用调度任务
     * @param scheduleId
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperLog(module=MODULE,action= OperLogActionEnum.ENABLE,detail="启用调度任务",isSaveRequestData=true)
    @ApiOperation(value = "启用调度任务", notes = "启用调度任务")
    @ApiImplicitParam(dataType = "String", name = "scheduleId", value = "调度任务ID", required = true)
    @RequiresPermissions("schedule:task:switch")
    @PutMapping(value = "/enableScheduleTask")
    public ResponseEntity<HttpResult> enableScheduleTask(
            @RequestParam(value = "scheduleId") String scheduleId,
            HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpResult result = new HttpResult(request.getRequestURI());

        TSysScheduleTask scheduleTask=scheduleTaskService.selectByPrimaryKey(scheduleId);

        scheduleTask.setIsEnable(true);
        scheduleTaskService.updateByPrimaryKeySelective(scheduleTask);

        schedulerService.enableSchedule(scheduleTask);
        result.setMessage("OK.");
        result.setStatus(HttpStatus.OK.value());
        return new ResponseEntity<>(result, HttpStatus.OK);

    }


    /***
     * 停用调度任务
     * @param scheduleId
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperLog(module=MODULE,action= OperLogActionEnum.DISABLE,detail="停用调度任务",isSaveRequestData=true)
    @ApiOperation(value = "停用调度任务", notes = "停用调度任务")
    @ApiImplicitParam(dataType = "String", name = "scheduleId", value = "调度任务ID", required = true)
    @RequiresPermissions("schedule:task:switch")
    @PutMapping(value = "/disableScheduleTask")
    public ResponseEntity<HttpResult> disableScheduleTask(
            @RequestParam(value = "scheduleId") String scheduleId,
            HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpResult result = new HttpResult(request.getRequestURI());

        TSysScheduleTask scheduleTask=scheduleTaskService.selectByPrimaryKey(scheduleId);

        scheduleTask.setIsEnable(false);
        scheduleTaskService.updateByPrimaryKeySelective(scheduleTask);

        if (null!=schedulerService.getTaskSchedulerMap(scheduleTask.getScheduleId())) {
            schedulerService.disableSchedule(scheduleTask);
        }

        result.setMessage("OK");
        result.setStatus(HttpStatus.OK.value());
        return new ResponseEntity<>(result, HttpStatus.OK);

    }


    /***
     * 立即执行调度任务
     * @param scheduleId
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperLog(module=MODULE,action= OperLogActionEnum.RUN,detail="立即执行调度任务",isSaveRequestData=true)
    @ApiOperation(value = "立即执行调度任务", notes = "立即执行调度任务")
    @ApiImplicitParam(dataType = "String", name = "scheduleId", value = "调度任务ID", required = true)
    @RequiresPermissions("schedule:task:execute")
    @GetMapping(value = "/runningScheduleTask")
    public ResponseEntity<HttpResult> runningScheduleTask(
            @RequestParam(value = "scheduleId") String scheduleId,
            HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpResult result = new HttpResult(request.getRequestURI());

        TSysScheduleTask scheduleTask=scheduleTaskService.selectByPrimaryKey(scheduleId);

        schedulerService.runningScheduleTask(scheduleTask);
        result.setMessage("OK");
        result.setStatus(HttpStatus.OK.value());
        return new ResponseEntity<>(result, HttpStatus.OK);

    }
}
